package org.myOrg.spetrum.spectrumStruct;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.myOrg.spetrum.combination.Tuple;

public class TupleStructSets {
	private List<TupleAnalyseStruct> sets;
	private List<Tuple> bugs;

	public TupleStructSets() {
		sets = new ArrayList<TupleAnalyseStruct>();
		bugs = new ArrayList<Tuple>();
	}

	public Iterator<TupleAnalyseStruct> iterator() {
		return sets.iterator();
	}

	public int size() {
		return sets.size();
	}

	public void initHeads(List<Tuple> heads) {
		Iterator<Tuple> itr = heads.iterator();
		if (heads.size() == 1) {
			Tuple tuple = itr.next();
			TupleAnalyseStruct head = initHead(tuple);
			head.setTested(true);
			head.setPassOrFail(false);
		} else
			while (itr.hasNext()) {
				initHead(itr.next());
			}
	}

	public TupleAnalyseStruct initHead(Tuple head) {
		TupleAnalyseStruct headStruct;
		headStruct = getTupleAnalyseStructByTuple(head);
		if (headStruct == null) {
			headStruct = new TupleAnalyseStruct(head);
			sets.add(headStruct);

			List<Tuple> childs = head.getChildTuples();
			Iterator<Tuple> itr = childs.iterator();
			while (itr.hasNext()) {
				Tuple child = itr.next();
				TupleAnalyseStruct temp = initHead(child);
				temp.addDirectFather(headStruct);
				headStruct.addDirectChild(temp);
			}
		}
		return headStruct;
	}

	/**
	 * 
	 * this function can be better
	 * @param tuple
	 * @return
	 */
	public TupleAnalyseStruct getTupleAnalyseStructByTuple(Tuple tuple) {
		Iterator<TupleAnalyseStruct> itr = sets.iterator();
		while (itr.hasNext()) {
			TupleAnalyseStruct temp = itr.next();
			if (temp.getTuple().equals(tuple))
				return temp;
		}
		return null;
	}
	
	public List<TupleAnalyseStruct> getTupleAnalyseStructByIsTested(
			boolean isTested) {
		List<TupleAnalyseStruct> result = new ArrayList<TupleAnalyseStruct>();
		Iterator<TupleAnalyseStruct> itr = sets.iterator();
		while (itr.hasNext()) {
			TupleAnalyseStruct temp = itr.next();
			if (temp.isTested() == isTested) {
				result.add(temp);
			}
		}
		return result;
	}

	public List<TupleAnalyseStruct> getTupleAnalyseStructByPassOrFail(
			boolean passOrFail) {
		List<TupleAnalyseStruct> tested = getTupleAnalyseStructByIsTested(true);
		List<TupleAnalyseStruct> result = new ArrayList<TupleAnalyseStruct>();
		Iterator<TupleAnalyseStruct> itr = tested.iterator();
		while (itr.hasNext()) {
			TupleAnalyseStruct temp = itr.next();
			if (temp.isPassOrFail() == passOrFail)
				result.add(temp);
		}
		return result;
	}

	public TupleAnalyseStruct getMaxTestedValuable() {
		Iterator<TupleAnalyseStruct> itr = this.sets.iterator();
		double max = 0;
		TupleAnalyseStruct result = null;
		while (itr.hasNext()) {
			TupleAnalyseStruct temp = itr.next();
			if (temp.getTestValuable() > max) {
				max = temp.getTestValuable();
				result = temp;
			}
		}
		return result;
	}

	public List<Tuple> getBugTuple() {
		if (bugs.size() == 0) {
			List<TupleAnalyseStruct> fails = this
					.getTupleAnalyseStructByPassOrFail(false);
			Iterator<TupleAnalyseStruct> itr = fails.iterator();
			while (itr.hasNext()) {
				TupleAnalyseStruct current = itr.next();
				Iterator<TupleAnalyseStruct> childs = current.getDirectChilds()
						.iterator();
				boolean isBug = true;
				while (childs.hasNext()) {
					if (!childs.next().isPassOrFail()) {
						isBug = false;
						break;
					}
				}
				if (isBug) {
					bugs.add(current.getTuple());
				}
			}
		}
		return bugs;

	}

	public void clear() {
		this.bugs.clear();
		this.sets.clear();
	}

}
